<!--
 * @Author: xinqiao lxq1990.0716@qq.com
 * @Date: 2023-11-29 10:57:44
 * @LastEditors: xinqiao lxq1990.0716@qq.com
 * @LastEditTime: 2024-01-10 17:23:06
 * @FilePath: \partal\src\components\Menu\code\Menu.vue
 * @Description: 菜单组件
-->

<script lang="ts" setup>
  import { computed, watch, reactive } from 'vue'
  import { useRouter, useRoute } from 'vue-router'
  import { getDevelopMenus, getComponentMenus, getDesignMenus, getProjectMenus } from '@/config/menu'
  import { usePlant } from '@/stores/plant'
  import { menuPng } from '@/enum/imageEnum'
  import { PLANTTYPE_ENUM } from '@/enum/globalEnum'
  import { PAGE_DEVELOP_GUIDE } from '@/enum/pageEnum'

  const router = useRouter(), route = useRoute()
  const plant = usePlant()

  /** 菜单 */
  const menus = reactive<IParentMenu[]>([])
  /**
   * 重载菜单
   * @param plantType 平台类型
   */
  const reloadMenu = (async (plantType: PLANTTYPE_ENUM) => {
    menus.length = 0
    menus.push(getDevelopMenus(plantType))
    menus.push(await getComponentMenus(plantType))
    menus.push(getDesignMenus())
    menus.push(getProjectMenus())
    refreshMenuChecked(route.path)
  })
  /** 监听平台变化，重载菜单（开发指南-概述） */
  watch(
    () => plant.plantType,
    (newVal, oldVal) => {
      setTimeout(() => {
        reloadMenu(newVal)
        if (oldVal) router.replace({ path: PAGE_DEVELOP_GUIDE })
      }, 100)
    },
    { immediate: true }
  )

  /**
   * 刷新菜单的选中状态
   * @param routePath 路由链接
   */
  const refreshMenuChecked = (routePath: string) => {
    const routes = routePath.split('/')
    const firstRoute = `/${routes[1]}`
    const secondRoute = routes[2] ? `/${routes[2]}` : ''
    const thirdRoute = routes[3] ? `/${routes[3]}` : ''
    const forthRoute = routes[4] ? `/${routes[4]}` : ''
    menus.forEach((first: IParentMenu) => {
      if (first.path === firstRoute) first.expanded = true
      first.checked = false
      first.children.forEach((second: IChildMenu) => {
        // 开发指南+设计指南+项目案例：二级菜单
        if (first.name !== 'component') {
          second.checked = second.fullPath === `${firstRoute}${secondRoute}`
          if (second.checked) first.checked = true
        }
        // 组件：二级、三级、四级菜单
        else {
          second.children?.forEach((third: IChildMenu) => {
            third.children?.forEach((forth: IChildMenu) => {
              forth.checked = forth.fullPath === `${firstRoute}${secondRoute}${thirdRoute}${forthRoute}`
              if (forth.checked) first.checked = true
            })
          })
        }
      })
    })
  }
  // 监听路由变化，刷新菜单的选中状态
  watch(
    () => route.path,
    (value: string) => refreshMenuChecked(value),
    { immediate: true }
  )

  /**
   * 展开/收缩父菜单
   * @param group 父菜单
   */
  const expandGroup = (group: IParentMenu) => group.expanded = !group.expanded

  /**
   * 打开菜单
   * @param menu 子菜单
   */
  const openMenu = (menu: IChildMenu) => router.push({ path: menu.fullPath as string })

  /** 父菜单箭头图标 */
  const getGroupArrow = computed(() => {
    return (group: IParentMenu) => {
      if (group.checked) {
        return group.expanded ? menuPng.menuArrowUpActive : menuPng.menuArrowDownActive
      } else {
        return group.expanded ? menuPng.menuArrowUp : menuPng.menuArrowDown
      }
    }
  })
</script>

<template>
  <div class="menu">
    <div class="menu-group" v-for="(group, groupI) in menus" :key="`menu-group${groupI}`">
      <div class="menu-group-row" :class="group.checked ? 'active' : ''" @click="expandGroup(group)">
        <span class="name">{{ group.text }}</span>
        <img class="arrow" :src="getGroupArrow(group)" />
      </div>
      <!-- 开发指南+设计指南+项目案例：二级菜单 -->
      <template v-if="group.name !== 'component'">
        <div class="menu-group-children" v-if="group.expanded">
          <div
            class="child"
            :class="child.checked ? 'active' : ''"
            v-for="(child, childI) in group.children"
            :key="`menu-group-children-child${childI}`"
            @click="openMenu(child)"
          >
            {{ child.text }}
          </div>
        </div>
      </template>
      <!-- 组件：二级、三级、四级菜单 -->
      <template v-else>
        <div class="menu-group-children" v-if="group.expanded">
          <div class="component-second" v-for="(second, secondI) in group.children" :key="`component-second${secondI}`">
            <div class="component-third" v-for="(third, thirdI) in second.children" :key="`component-third${thirdI}`">
              <div class="component-third-title">{{ third.text }}</div>
              <div
                class="component-forth ellipsis-line-1"
                :class="forth.checked ? 'active' : ''"
                v-for="(forth, forthI) in third.children"
                :key="`component-forth${forthI}`"
                @click="openMenu(forth)"
              >
                {{ forth.text }}
              </div>
            </div>
          </div>
        </div>
      </template>
    </div>
  </div>
</template>

<style type="less" scoped>
  .menu {
    padding: 0 12px;

    > .menu-group {
      > .menu-group-row {
        height: 40px;
        display: flex;
        justify-content: space-between;
        align-items: center;
        cursor: pointer;
        > .name {
          margin-left: 12px;
          font-size: 16px;
          color: #4E5969;
          line-height: 40px;
        }
        > .arrow {
          margin-right: 12px;
          width: 16px;
          height: 16px;
        }
        &.active {
          > .name {
            color: #1677ff;
          }
        }
      }
      > .menu-group-children {
        > .child {
          height: 40px;
          margin-top: 4px;
          line-height: 40px;
          padding-left: 32px;
          cursor: pointer;
          &.active {
            background: #eee;
            border-radius: 2px;
            color: #1677ff;
          }
        }

        > .component-second {
          > .component-third {
            > .component-third-title {
              height: 40px;
              padding-left: 12px;
              line-height: 40px;
              color: #86909c;
            }
            > .component-forth {
              height: 40px;
              margin-top: 4px;
              padding-left: 32px;
              line-height: 40px;
              cursor: pointer;
              &.active {
                background: #eee;
                border-radius: 2px;
                color: #1677ff;
              }
              &:first-child {
                margin-top: 0;
              }
            }
          }
        }
      }
    }
  }
</style>
